

package cn.shengchao.examstar.pay.model.service;

import cn.hutool.core.collection.CollUtil;
import cn.shengchao.base.enums.ProductType;
import cn.shengchao.examstar.pay.acl.ports.client.IProductClient;
import cn.shengchao.examstar.pay.acl.ports.client.ProductPayPrice;
import cn.shengchao.examstar.pay.acl.ports.repositories.IOrderRepository;
import cn.shengchao.examstar.pay.model.aggregate.CreateOrderAggregate;
import cn.shengchao.examstar.pay.model.entity.OrderEntity;
import cn.shengchao.examstar.pay.model.entity.PayOrderEntity;
import cn.shengchao.examstar.pay.model.entity.ProductEntity;
import cn.shengchao.examstar.pay.model.entity.ShopCartEntity;
import cn.shengchao.examstar.pay.model.valobj.OrderStatusVO;
import cn.shengchao.examstar.product.domain.entity.FreeCourseKnowledgeProduct;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import top.continew.starter.core.validation.CheckUtils;

import java.math.BigDecimal;
import java.util.List;

/**
 * 通过抽象类来定义下单的标准
 */
@Slf4j
public abstract class AbstractOrderService implements IOrderService {

    protected final IOrderRepository repository;
    protected final IProductClient productPort;

    public AbstractOrderService(IOrderRepository repository, IProductClient productPort) {
        this.repository = repository;
        this.productPort = productPort;
    }

    @Override
    public PayOrderEntity createOrder(ShopCartEntity shopCartEntity) throws Exception {
        // 1. 查询当前用户是否存在掉单和未支付订单
        OrderEntity unpaidOrderEntity = repository.queryUnPayOrder(shopCartEntity);
        if (null != unpaidOrderEntity &&unpaidOrderEntity.getProductType().equals(ProductType.PRODUCT_THIRD_YCBDC.name())){
            if ("1903349492891995604".equals(unpaidOrderEntity.getProductId())){
                CheckUtils.throwIfNull(null, "您已购买了永久课程，无需续费!");
            }else if (!OrderStatusVO.PAY_WAIT.equals(unpaidOrderEntity.getOrderStatus())
                    && !OrderStatusVO.CREATE.equals(unpaidOrderEntity.getOrderStatus())
            ) {
                unpaidOrderEntity=null;
            }
        }
        if (null != unpaidOrderEntity && OrderStatusVO.PAY_WAIT.equals(unpaidOrderEntity.getOrderStatus())) {
            log.info("创建订单-存在，已存在未支付订单。userId:{} productId:{} orderId:{}", shopCartEntity.getUserId(), shopCartEntity
                    .getProductId(), unpaidOrderEntity.getOrderId());
            return PayOrderEntity.builder()
                    .orderId(unpaidOrderEntity.getOrderId())
                    .payInfo(JSON.parse(unpaidOrderEntity.getPayInfo()))
                    .build();
        } else if (null != unpaidOrderEntity && OrderStatusVO.CREATE.equals(unpaidOrderEntity.getOrderStatus())) {
            log.info("创建订单-存在，存在未创建支付单订单，创建支付单开始 userId:{} productId:{} orderId:{}", shopCartEntity
                    .getUserId(), shopCartEntity.getProductId(), unpaidOrderEntity.getOrderId());
            PayOrderEntity payOrderEntity = this.doPrepayOrder(shopCartEntity.getUserId(), shopCartEntity
                    .getOpenId(), shopCartEntity.getAppid(), shopCartEntity.getProductId(), unpaidOrderEntity.getProductName(), unpaidOrderEntity
                    .getOrderId(), shopCartEntity.getIp(), shopCartEntity.getType(), unpaidOrderEntity.getTotalAmount());
            return PayOrderEntity.builder()
                    .orderId(payOrderEntity.getOrderId())
                    .payInfo(payOrderEntity.getPayInfo())
                    .build();
        } else if (null != unpaidOrderEntity) {
            CheckUtils.throwIfNull(null, "请勿重复购买!");
        }


        // 2. 查询商品 & 聚合订单
        //需要产品信息价格
        ProductPayPrice productPayPrice = productPort.calculateProductPayPrice(shopCartEntity
                .getProductId(), shopCartEntity.getSubProductIds());
        ProductEntity productEntity = productPayPrice.getProduct();
        //组装订单
        OrderEntity orderEntity = CreateOrderAggregate.buildOrderEntity(productEntity.getProductId(), productEntity
                .getProductName(), JSON.toJSONString(productEntity));
        orderEntity.setPrice(productEntity.getPrice());
        orderEntity.setTotalAmount(productPayPrice.getPayPrice());
        orderEntity.setDiscountInfo(productPayPrice.getDiscountInfo());
        orderEntity.setProductType(productEntity.getProductType());
        orderEntity.setPayType(shopCartEntity.getType());
        //组装子订单
        orderEntity.addAllOrderItemEntities(productPayPrice.getSubProducts());
        CreateOrderAggregate orderAggregate = CreateOrderAggregate.builder()
                .userId(shopCartEntity.getUserId())
                .shareCode(shopCartEntity.getShareCode())
                .productEntity(productEntity)
                .orderEntity(orderEntity)
                .build();

        // 3. 保存订单 - 保存一份订单，再用订单生成ID生成支付单信息
        this.doSaveOrder(orderAggregate);

        if (orderEntity.getTotalAmount().doubleValue() > 0) {
            // 4. 创建支付单
            PayOrderEntity payOrderEntity = this.doPrepayOrder(shopCartEntity.getUserId(), shopCartEntity
                    .getOpenId(), shopCartEntity.getAppid(),productEntity.getProductId(), productEntity.getProductName(), orderEntity
                    .getOrderId(), shopCartEntity.getIp(), shopCartEntity.getType(), orderEntity.getTotalAmount());
            log.info("创建订单-完成，生成支付单。userId: {} orderId: {} pageInfo: {}", shopCartEntity.getUserId(), orderEntity
                    .getOrderId(), payOrderEntity.getPayInfo());
            return PayOrderEntity.builder()
                    .orderId(payOrderEntity.getOrderId())
                    .payInfo(payOrderEntity.getPayInfo())
                    .build();

        }
        log.info("创建订单-完成，无需支付。userId: {} orderId: {}", shopCartEntity.getUserId(), orderEntity.getOrderId());
//        this.changeOrderPaySuccess(orderEntity.getOrderId());
//        return PayOrderEntity.builder().orderId(orderEntity.getOrderId()).payInfo("0元订单").build();
        return null;
    }
    @Override
    public FreeCourseKnowledgeProduct loadFreeProduct(Long productId){
        return productPort.loadFreeProductNode(productId);
    }
    @Override
    public String createFreeLockOrder(Long userId,String orderId,Long courseId, Long productId) {
        ProductPayPrice productPayPrice = productPort.calculateProductPayPrice(courseId.toString(), List.of(productId));
        ProductEntity productEntity = productPayPrice.getProduct();
        productEntity.setPrice(BigDecimal.ZERO);
        productEntity.setDiscountPrice(BigDecimal.ZERO);
        //组装订单
        OrderEntity orderEntity = CreateOrderAggregate.buildOrderEntityForOrderId(orderId,productEntity.getProductId(), productEntity
                .getProductName(), JSON.toJSONString(productEntity));
        orderEntity.setPrice(BigDecimal.ZERO);
        orderEntity.setTotalAmount(BigDecimal.ZERO);
        orderEntity.setDiscountInfo("{product:free}");
        orderEntity.setProductType(productEntity.getProductType());
        orderEntity.setPayType("0");
        //直接设置为等待支付
        orderEntity.setOrderStatus(OrderStatusVO.CREATE);
        //组装子订单
        if (CollUtil.isNotEmpty(productPayPrice.getSubProducts())){
            productPayPrice.getSubProducts().forEach(a->a.setPrice(BigDecimal.ZERO));
            productPayPrice.getSubProducts().forEach(a->a.setDiscountPrice(BigDecimal.ZERO));
        }
        orderEntity.addAllOrderItemEntities(productPayPrice.getSubProducts());
        CreateOrderAggregate orderAggregate = CreateOrderAggregate.builder()
                .userId(userId.toString())
                .shareCode("")
                .productEntity(productEntity)
                .orderEntity(orderEntity)
                .build();
        // 3. 保存订单 - 保存一份订单，再用订单生成ID生成支付单信息
        this.doSaveOrder(orderAggregate);
        return orderEntity.getOrderId();
    }
    @Override
    public ProductPayPrice calculate(ShopCartEntity shopCartEntity) {
        return productPort.calculateProductPayPrice(shopCartEntity.getProductId(), shopCartEntity.getSubProductIds());
    }

    /**
     * 保存订单
     *
     * @param orderAggregate 订单聚合
     */
    protected abstract void doSaveOrder(CreateOrderAggregate orderAggregate);

    /**
     * 预支付订单生成
     *
     * @param userId      用户ID
     * @param productId   商品ID
     * @param productName 商品名称
     * @param orderId     订单ID
     * @param totalAmount 支付金额
     * @return 预支付订单
     */
    protected abstract PayOrderEntity doPrepayOrder(String userId,
                                                    String openId,
                                                    String appid,
                                                    String productId,
                                                    String productName,
                                                    String orderId,
                                                    String ip,
                                                    String type,
                                                    BigDecimal totalAmount) throws Exception;

}
